//examples目录是官方的一些例子 本次使用的是echo_server\echo_server.cpp
//该原程序只支持一对一发送后回复
//改造后可以通知所有连接上来的客户端。
//编译 g++ echo_server.cpp -lboost_system -lboost_chrono
 
#include <websocketpp/config/asio_no_tls.hpp>
 
#include <websocketpp/server.hpp>
 
#include <iostream>
#include <list>
 
#include <bits/std_function.h> //添加function头文件
 
typedef websocketpp::server<websocketpp::config::asio> server;
 
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
 
// pull out the type of messages sent by our config
typedef server::message_ptr message_ptr;
 
std::list<websocketpp::connection_hdl> vgdl;
 
// Define a callback to handle incoming messages
void on_message(server *s, websocketpp::connection_hdl hdl, message_ptr msg)
{
    // std::cout << "on_message called with hdl: " << hdl.lock().get()
    //           << " and message: " << msg->get_payload()
    //           << std::endl;
 
    // check for a special command to instruct the server to stop listening so
    // it can be cleanly exited.
    if (msg->get_payload() == "stop-listening")
    {
        s->stop_listening();
        return;
    }
 
    for (auto it = vgdl.begin(); it != vgdl.end(); it++)
    {
        if (it->expired())//移除连接断开的
        {
            it = vgdl.erase(it);
            continue;
        }
        if (it != vgdl.end())
            s->send(*it, msg->get_payload(), msg->get_opcode());
        // t.wait();
    }
 
    // try {
    //     s->send(hdl, msg->get_payload()+std::string("aaaaa"), msg->get_opcode());
    // } catch (websocketpp::exception const & e) {
    //     std::cout << "Echo failed because: "
    //               << "(" << e.what() << ")" << std::endl;
    // }
}
//将每个连接存入容器
void on_open(websocketpp::connection_hdl hdl)
{
    std::string msg = "link OK";
    printf("%s\n", msg.c_str());
    // printf("fd %d\n",(int)hdl._M_ptr());
    vgdl.push_back(hdl);
}
 
void on_close(websocketpp::connection_hdl hdl)
{
    std::string msg = "close OK";
    printf("%s\n", msg.c_str());
}
int main()
{
    // Create a server endpoint
    server echo_server;
 
    try
    {
        // Set logging settings 设置log
        echo_server.set_access_channels(websocketpp::log::alevel::all);
        echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
 
        // Initialize Asio 初始化asio
        echo_server.init_asio();
 
        // Register our message handler
        // 绑定收到消息后的回调
        echo_server.set_message_handler(bind(&on_message, &echo_server, ::_1, ::_2));
        //当有客户端连接时触发的回调
        std::function<void(websocketpp::connection_hdl)> f_open;
        f_open = on_open;
        echo_server.set_open_handler(websocketpp::open_handler(f_open));
        //关闭是触发
        std::function<void(websocketpp::connection_hdl)> f_close(on_close);
        echo_server.set_close_handler(f_close);
        // Listen on port 9002
        echo_server.listen(9002);//监听端口
 
        // Start the server accept loop
        echo_server.start_accept();
 
        // Start the ASIO io_service run loop
        echo_server.run();
    }
    catch (websocketpp::exception const &e)
    {
        std::cout << e.what() << std::endl;
    }
    catch (...)
    {
        std::cout << "other exception" << std::endl;
    }
}
